package protocol;

import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ListeningGameThread {

	private final int MAX_MESSAGE_SIZE;
	private boolean running, connectionConfirmed;
	
	private MulticastSocket privateGameSocketToReceiveMulticast;
	private DatagramSocket datagramSocket;
	private InetAddress localIp;
	
	public ListeningGameThread(int maxMessageSize, MulticastSocket privateGameSocketToReceiveMulticast, DatagramSocket datagramSocket, InetAddress localIp) {
		this.MAX_MESSAGE_SIZE = maxMessageSize;
		this.running = true;
		
		this.privateGameSocketToReceiveMulticast = privateGameSocketToReceiveMulticast;
		this.datagramSocket = datagramSocket;
		this.localIp = localIp;
	}
	
	public void startThread() {
		
//		new Thread(new Runnable() {
//
//			@Override
//			public void run() {
//
//				while(running) {
//
//					byte[] buf = new byte[MAX_MESSAGE_SIZE];
//					DatagramPacket paquete = new DatagramPacket(buf, buf.length);
//					try {
//						privateGameSocketToReceiveMulticast.receive(paquete);
//
//						String message = new String(buf);
//
//						// Checking if is a sync message
//						message = XmlParser.readByTag(message, P.ENCABEZADO, 0);
//						if(message != null) {
//							if(XmlParser.readByTag(message, P.CONNECTION_SYNC, 0) != null) {
//
//								String confirmation = XmlParser.readByTag(message, P.CONFIRMATION, 0);
//								// If is a confirmation message
//								if(confirmation != null) {
//									if(!connectionConfirmed) {
//										String ipHost = XmlParser.readByTag(message, P.HOST_IP, 0);
//										if(localIp.equals(ipHost)) {
//											if(confirmation.equals(P.TRUE)) {
//												confimationListener.onConnectionConfirmed(true);
//											} else if(confirmation.equals(P.FALSE)){
//												confimationListener.onConnectionConfirmed(false);
//												running = false;
//											}
//											connectionConfirmed = true;
//										}
//									}
//								} else {
//
//									try {
//										int countDown = Integer.valueOf(XmlParser.readByTag(message, P.COUNT_DOWN, 0));
//										if(countDown < consecutive) {
//											staredGame = true;
//											consecutive = countDown;
//											fuzziness --; // If I receive the message it means the network is not very fuzzy
//											long timeDifference = System.currentTimeMillis() - Long.valueOf(XmlParser.readByTag(message, P.LOCALTIME, 0));
//											startingGameListener.onGameStart(timeDifference, countDown);
//											String usersIpString = XmlParser.readByTag(message, P.USERS_LIST_IP, 0);
//											String usersNamesString = XmlParser.readByTag(message, P.USERS_LIST_NAMES, 0);
//											Print.print("Users Ips: "+usersIpString);
//											Print.print("Users Names: "+usersNamesString);
//											String[] usersIp = usersIpString.split(" ");
//											String[] usersNames = usersNamesString.split(" ");
//											for (int i = 0; i < usersIp.length; i++) {
//												User nuevo = new User(usersIp[i], usersNames[i]);
//												Print.print("Usuario agregado: "+nuevo.toString());
//												if(!usersIp[i].equals(manager.localIp))
//													usersInRoom.put(usersIp[i], nuevo);
//											}
//										}
//									} catch(Exception e) {
//										Print.print("Error recibiendo la lista de usuarios");
//									}
//								}
//							}
//
//							// Receiving a message during the game
//							else {
//
//								// Getting sender
//								User sender = usersInRoom.get(paquete.getAddress().getHostAddress());
//
//								if(sender != null) {
//
//									String ack = XmlParser.readByTag(message, P.ACK, 0);
//									if(ack != null) {
//										long ackValue = Integer.valueOf(XmlParser.readByTag(message, P.ACK, 0));
//										//											Print.print("ACK "+ackValue);
//										int fuzyDifference = (int) (ackValue - lastFuzzyIndexReceived);
//										if(fuzyDifference > 0) {
//											if(fuzyDifference == 1 || fuzyDifference < (fuzziness/3)) {
//												if(fuzyDifference < DEFAULT_MINIMUM_VALUE && fuzziness > DEFAULT_MINIMUM_VALUE)
//													fuzziness --;
//												if(fuzziness > DEFAULT_MINIMUM_VALUE)
//													fuzziness --;
//											} else if(fuzyDifference > (fuzziness/2)) {
//												fuzziness += (fuzyDifference/3);
//												if(fuzziness > DEFAULT_TRUSTED_VALUE)
//													fuzziness = DEFAULT_TRUSTED_VALUE;
//											}
//											lastFuzzyIndexReceived = ackValue;
//											if(sendingTime > 100000) {
//												sendingTime = System.currentTimeMillis()-sendingTime;
//												Print.print("ACK received "+sendingTime+"ms after sending the message.");
//											}
//										}
//										Print.print(fuzziness+(fuzziness < 10 ? "  " : " ")+ackValue);
//
//									} else {
//
//										String consecutiveText = XmlParser.readByTag(message, P.CONSECUTIVE, 0);
//										String fuzzyControlText = XmlParser.readByTag(message, P.FUZZI_CONTROL, 0);
//										long msjConsecutive = Long.valueOf(consecutiveText);
//										//											long fuzzyIndex = Long.valueOf(fuzzyControlText);
//										//											Print.print("receiving -> "+consecutiveText+"/"+fuzzyControlText);
//
//										if(msjConsecutive > sender.lastConsecutiveIndex) {
//											listener.onNewMessage(XmlParser.readByTag(message, P.PAYLOAD, XmlParser.guessNextLimit(P.CONSECUTIVE, consecutiveText, 0)) +
//													XmlParser.guessNextLimit(P.FUZZI_CONTROL, fuzzyControlText, 0), sender);
//											sender.lastConsecutiveIndex = msjConsecutive;
//										}
//										// ACK
//										buf = ("<"+P.ENCABEZADO+"><"+P.ACK+">"+fuzzyControlText+"</"+P.ACK+"></"+P.ENCABEZADO+">").getBytes();
//										sendingDatagram.send(new DatagramPacket(buf, buf.length, manager.broadcastIP, privatePort));
//									}
//
//								}
//								//									else if(manager.localIp.equals(paquete.getAddress().getHostAddress())) {
//								//									}
//							}
//						} else {
//							Print.print("Message format incorrect!!");
//						}
//
//					} catch (Exception e) {
//						Print.print("RoomConnection-listeningGameThread()-Exception!!");
//						e.printStackTrace();
//					}
//
//				}
//
//			}
//		}).start();
//
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
//
//		new Thread(new Runnable() {
//
//			@Override
//			public void run() {
//
//				while(running) {
//
//					byte[] buf = new byte[MAX_MESSAGE_SIZE];
//					DatagramPacket paquete = new DatagramPacket(buf, buf.length);
//					try {
//						datagramSocket.receive(paquete);
//
//						String message = new String(buf);
//
//						// Checking if is a sync message
//						message = XmlParser.readByTag(message, P.ENCABEZADO, 0);
//						if(message != null) {
//							if(XmlParser.readByTag(message, P.CONNECTION_SYNC, 0) != null) {
//
//								String confirmation = XmlParser.readByTag(message, P.CONFIRMATION, 0);
//								// If is a confirmation message
//								if(confirmation != null) {
//									if(!connectionConfirmed) {
//										String ipHost = XmlParser.readByTag(message, P.HOST_IP, 0);
//										if(manager.localIp.equals(ipHost)) {
//											if(confirmation.equals(P.TRUE)) {
//												confimationListener.onConnectionConfirmed(true);
//											} else if(confirmation.equals(P.FALSE)){
//												confimationListener.onConnectionConfirmed(false);
//												running = false;
//											}
//											connectionConfirmed = true;
//										}
//									}
//								} else {
//
//									try {
//										int countDown = Integer.valueOf(XmlParser.readByTag(message, P.COUNT_DOWN, 0));
//										if(countDown < consecutive) {
//											staredGame = true;
//											consecutive = countDown;
//											fuzziness --; // If I receive the message it means the network is not very fuzzy
//											long timeDifference = System.currentTimeMillis() - Long.valueOf(XmlParser.readByTag(message, P.LOCALTIME, 0));
//											startingGameListener.onGameStart(timeDifference, countDown);
//											String usersIpString = XmlParser.readByTag(message, P.USERS_LIST_IP, 0);
//											String usersNamesString = XmlParser.readByTag(message, P.USERS_LIST_NAMES, 0);
//											Print.print("Users Ips: "+usersIpString);
//											Print.print("Users Names: "+usersNamesString);
//											String[] usersIp = usersIpString.split(" ");
//											String[] usersNames = usersNamesString.split(" ");
//											for (int i = 0; i < usersIp.length; i++) {
//												User nuevo = new User(usersIp[i], usersNames[i]);
//												Print.print("Usuario agregado: "+nuevo.toString());
//												if(!usersIp[i].equals(manager.localIp))
//													usersInRoom.put(usersIp[i], nuevo);
//											}
//										}
//									} catch(Exception e) {
//										Print.print("Error recibiendo la lista de usuarios");
//									}
//								}
//							}
//
//							// Receiving a message during the game
//							else {
//
//								// Getting sender
//								User sender = usersInRoom.get(paquete.getAddress().getHostAddress());
//
//								if(sender != null) {
//
//									String ack = XmlParser.readByTag(message, P.ACK, 0);
//									if(ack != null) {
//										long ackValue = Integer.valueOf(XmlParser.readByTag(message, P.ACK, 0));
//										int fuzyDifference = (int) (ackValue - lastFuzzyIndexReceived);
//										if(fuzyDifference > 0) {
//											if(fuzyDifference == 1 || fuzyDifference < (fuzziness/3)) {
//												if(fuzyDifference < DEFAULT_MINIMUM_VALUE && fuzziness > DEFAULT_MINIMUM_VALUE)
//													fuzziness --;
//												if(fuzziness > DEFAULT_MINIMUM_VALUE)
//													fuzziness --;
//											} else if(fuzyDifference > (fuzziness/2)) {
//												fuzziness += (fuzyDifference/3);
//												if(fuzziness > DEFAULT_TRUSTED_VALUE)
//													fuzziness = DEFAULT_TRUSTED_VALUE;
//											}
//											lastFuzzyIndexReceived = ackValue;
//											if(sendingTime > 100000) {
//												sendingTime = System.currentTimeMillis()-sendingTime;
//												Print.print("ACK received "+sendingTime+"ms after sending the message.");
//											}
//										}
//										Print.print(fuzziness+(fuzziness < 10 ? "  " : " ")+ackValue);
//
//									} else {
//
//										String consecutiveText = XmlParser.readByTag(message, P.CONSECUTIVE, 0);
//										String fuzzyControlText = XmlParser.readByTag(message, P.FUZZI_CONTROL, 0);
//										long msjConsecutive = Long.valueOf(consecutiveText);
//
//										if(msjConsecutive > sender.lastConsecutiveIndex) {
//											listener.onNewMessage(XmlParser.readByTag(message, P.PAYLOAD, XmlParser.guessNextLimit(P.CONSECUTIVE, consecutiveText, 0)), sender);
//											sender.lastConsecutiveIndex = msjConsecutive;
//										}
//										// ACK
//										buf = ("<"+P.ENCABEZADO+"><"+P.ACK+">"+fuzzyControlText+"</"+P.ACK+"></"+P.ENCABEZADO+">").getBytes();
//										sendingDatagram.send(new DatagramPacket(buf, buf.length, manager.broadcastIP, privatePort));
//									}
//
//								}
//							}
//						} else {
//							Print.print("Message format incorrect!!");
//						}
//
//					} catch (Exception e) {
//						Print.print("RoomConnection-listeningGameThread()-Exception!!");
//						e.printStackTrace();
//					}
//
//				}
//
//			}
//		}).start();
//
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
//		// ****************************************************************************************************************
		
	}
	
}
